#include "app_buffer.h"

typedef struct
{
    char *ptr;    // 缓冲区指针
    int capacity; // 缓冲区容量
    int len;      // 已经存储的字节数
} sub_buffert_t;

struct buffer
{
    sub_buffert_t *sub_buffers[2];
    int read_index;  // 哪个子缓冲区用于读
    int write_index; // 哪个子缓冲区用于写

    pthread_mutex_t read_mutext;  // 读锁
    pthread_mutex_t write_mutext; // 写锁
};
/**
 * @brief 初始化子缓冲区
 *
 * @param capacity 缓冲区容量
 * @return buffer_t* 缓冲区指针
 */
sub_buffert_t *app_buffer_init_sub_buffer(int capacity)
{
    sub_buffert_t *sub_buffer = (sub_buffert_t *)malloc(sizeof(sub_buffert_t));
    if (sub_buffer == NULL)
    {
        perror("malloc sub_buffer error");
        return NULL;
    }
    sub_buffer->ptr = (char *)malloc(capacity);
    if (sub_buffer->ptr == NULL)
    {
        perror("malloc sub_buffer->ptr error");
        free(sub_buffer);
        return NULL;
    }
    memset(sub_buffer->ptr, 0, capacity);

    sub_buffer->capacity = capacity;
    sub_buffer->len = 0;

    return sub_buffer;
}

aa app_buffer_init_1(int capacity)
{
    buffer_t *buffer = (buffer_t *)malloc(sizeof(buffer_t));
    if (buffer == NULL)
    {
        perror("缓冲区分配内存失败");
        return NULL;
    }

    buffer->sub_buffers[0] = app_buffer_init_sub_buffer(capacity);
    if (buffer->sub_buffers[0] == NULL)
    {
        log_error("子缓冲区0申请失败");
        return NULL;
    }
    buffer->sub_buffers[1] = app_buffer_init_sub_buffer(capacity);
    if (buffer->sub_buffers[1] == NULL)
    {
        log_error("子缓冲区1申请失败");
        return NULL;
    }

    buffer->read_index = 0;
    buffer->write_index = 1;

    pthread_mutex_init(&buffer->read_mutext, NULL);
    pthread_mutex_init(&buffer->write_mutext, NULL);

    log_info("缓冲区申请成功");

    return (aa)buffer;
}
gate_status_t app_buffer_write_1(aa cc, char *data, char len)
{
    buffer_t *buffer = (buffer_t *)cc;
}

/**
 * @brief 创建一个缓冲区
 *
 * @param capacity 缓冲区容量
 * @return buffer_t 缓冲区对象
 */
buffer_t *app_buffer_init(int capacity)
{
    buffer_t *buffer = (buffer_t *)malloc(sizeof(buffer_t));
    if (buffer == NULL)
    {
        perror("缓冲区分配内存失败");
        return NULL;
    }

    buffer->sub_buffers[0] = app_buffer_init_sub_buffer(capacity);
    if (buffer->sub_buffers[0] == NULL)
    {
        log_error("子缓冲区0申请失败");
        return NULL;
    }
    buffer->sub_buffers[1] = app_buffer_init_sub_buffer(capacity);
    if (buffer->sub_buffers[1] == NULL)
    {
        log_error("子缓冲区1申请失败");
        return NULL;
    }

    buffer->read_index = 0;
    buffer->write_index = 1;

    pthread_mutex_init(&buffer->read_mutext, NULL);
    pthread_mutex_init(&buffer->write_mutext, NULL);

    log_info("缓冲区申请成功");

    return buffer;
}

void app_buffer_deinit(buffer_t *buffer)
{
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[0]);

    free(buffer->sub_buffers[1]->ptr);
    free(buffer->sub_buffers[1]);

    pthread_mutex_destroy(&buffer->read_mutext);
    pthread_mutex_destroy(&buffer->write_mutext);

    free(buffer);
}

/**
 * @brief 向指定的缓冲区写入指定长度的数据
 *
 * @param buffer
 * @param data
 * @param len
 * @return gate_status_t
 */
gate_status_t app_buffer_write(buffer_t *buffer, char *data, char len)
{
    pthread_mutex_lock(&buffer->write_mutext);
    // 1.找到写缓冲区
    sub_buffert_t *w_buffer = buffer->sub_buffers[buffer->write_index];

    // 2. 判断缓冲区释放能写入要写入的数据. 数据的长度也要写入到缓冲区中(用一个字节)
    // 4abcd
    if (w_buffer->capacity - w_buffer->len < len + 1)
    {
        log_error("缓冲区容量不足: 剩余空间=%d, 要写入数据长度=%d",
                  w_buffer->capacity - w_buffer->len,
                  len + 1);
        pthread_mutex_unlock(&buffer->write_mutext);
        return GATE_ERROR;
    }

    // 3. 开始向缓冲区写数据  4abcd
    // 3.1 先写长度 4
    w_buffer->ptr[w_buffer->len] = len;
    // 3.2 再写数据 abcd
    memcpy(w_buffer->ptr + w_buffer->len + 1, data, len);
    // 3.3 更新已经写入的数据的长度
    w_buffer->len += len + 1;
    pthread_mutex_unlock(&buffer->write_mutext);
    log_info("缓冲区写入成功");
    return GATE_OK;
}

/**
 * @brief
 *
 * @param buffer
 * @param data 存储读取到的数据的缓冲区
 * @param data_size 缓冲区的容量
 * @return int 实际读到的字节数
 */
int app_buffer_read(buffer_t *buffer, char data[], int data_size)
{
    pthread_mutex_lock(&buffer->read_mutext);

    sub_buffert_t *r_buffer = buffer->sub_buffers[buffer->read_index];

    if (r_buffer->len == 0)
    {
        // 交换缓冲区
        pthread_mutex_lock(&buffer->write_mutext);
        int tmp = buffer->read_index;
        buffer->read_index = buffer->write_index;
        buffer->write_index = tmp;
        pthread_mutex_unlock(&buffer->write_mutext);

        r_buffer = buffer->sub_buffers[buffer->read_index];
        if (r_buffer->len == 0)
        {
            // log_debug("buffer is empty");
            pthread_mutex_unlock(&buffer->read_mutext);
            return 0;
        }
    }

    // 读取数据
    // 先读长度
    char len = r_buffer->ptr[0];
    if (data_size < len)
    {
        log_error("读取的数据长度 %d 超过了传入的缓冲区的容量 %d", len, data_size);
        pthread_mutex_unlock(&buffer->read_mutext);
        return 0;
    }

    memcpy(data, r_buffer->ptr + 1, len);
    memmove(r_buffer->ptr, r_buffer->ptr + 1 + len, r_buffer->len - 1 - len);
    // 长度更新
    r_buffer->len -= 1 + len;

    pthread_mutex_unlock(&buffer->read_mutext);
    return len;
}
